; ******************************************************************************
; * demo_7seg.asm
; * LLP STUDIO SVP Peng
; * V1.0
; * 2023-08-29
; * 外部中断INT0、INT1联合调用
; * 主程序控制数码管1循环显示0 - 9；
; * 外中断0（INT0）、外中断1（INT1）发生时分别在数码管2与数码管3依次显示0 - 9；
; * 指定INT1为高优先级，INT0为低优先级
; * 功能观察：
; * 	高低优先级工作原理
; * 	高优先级可以中断低优先级
; * 	同一优先级不能相互中断
; ******************************************************************************

ORG 0
SJMP Start  ; 跳过中断向量
ORG 03H  ; INT0中断向量
SJMP Int_0  ; 执行Int_0中断子程序
ORG 13H  ; INT1中断向量起始地址
SJMP Int_1  ; 执行Int_1中断子程序
ORG 30H

Start:
MOV IE, #10000101B
MOV SP, #80H
; 采用下降沿触发 MOV TCON, #05H
SETB IT0
SETB IT1
SETB PX1  ; 设定优先级 SETB IP.2
MOV DPTR, #Table

Renew:
MOV R0, #10  ; 10次输出
MOV R1, #0  ; 设定输出初始值

Loop:
; 由于是Loop等待中断后响应，一定要在这里将数码管回到原位，
; 否则回到主程序数码管还在中断的位置显示
MOV P2, #1CH
MOV A, R1
MOVC A, @A + DPTR
MOV P0, A
CALL Delay
INC R1
DJNZ R0, Loop
JMP Renew  ; 重新开始一轮数字显示
; 主控程序结束

; 中断INT1子程序开始
Int_1:
PUSH PSW
PUSH ACC
CLR RS1
SETB RS0  ; 切换到RB1
; 循环开始
MOV R4, #2  ; 定义中断数码管内容9 - 0循环减1，计2轮

IntRe3:
MOV R0, #10  ; 设定10次循环
MOV R1, #9  ; 设定输出初始值

IntLoop1:
MOV P2, #18H
MOV A, R1
MOVC A, @A + DPTR
MOV P0, A
CALL Delay
DEC R1
DJNZ R0, IntLoop1
DJNZ R4, IntRe3
POP ACC
POP PSW
RETI
; INT1中断子程序结束

; 中断INT0子程序开始
Int_0:
PUSH PSW
PUSH ACC
CLR RS0
SETB RS1  ; 切换到RB2
; 循环开始
MOV R4, #2

IntRe4:
MOV R0, #10
MOV R1, #9

IntLoop2: 
MOV P2, #14H
MOV A, R1
MOVC A, @A + DPTR
MOV P0, A
CALL Delay
DEC R1
DJNZ R0, IntLoop2
DJNZ R4, IntRe4
POP ACC
POP PSW
RETI
; INT0中断子程序结束

; 0.5 s延时子程序
Delay:
MOV R7, #4
D1:
MOV R6, #200
D2:
MOV R5, #250
DJNZ R5, $
DJNZ R6, D2
DJNZ R7, D1
RET

Table:
DB 0X3F, 0X06, 0X5B, 0X4F, 0X66, 0X6D, 0X7D, 0X07, 0X7F, 0X6F

END
